local skynet = require "skynet"
local cluster = require "skynet.cluster"
local tabletool = require "tabletool"
local timetool = require "timetool"
local timer = require "timer"
local filelog = require "filelog"
local configdao = require "configdao"
local base = require "base"
local md5 = require "md5"
local json = require "cjson"
json.encode_sparse_array(true, 1, 1)

require "imenum"

local TalkLogic = {}
local service = nil

function TalkLogic.init(caller)
	service = caller
end

function TalkLogic.check_player_is_vip(rid)
    local request_url = "http://api.daili.com/index/get_vip_info"
    local sm_key = configdao.get_common_conf("sm_key") or ""
    local curtime = timetool.get_time()
    local sign = md5.sumhexa(curtime .. sm_key) .. curtime
    if not rid then return false end
    --发送http请求
    request_url = request_url .. "?rid=" .. rid .. "&sign=" .. sign .. "&strtime=" .. curtime
    local status, result = skynet.pcall(skynet.call, ".httpservice", "lua", "send_http_request", rid, request_url)
    if status == true and result ~= false then
        local deresult = json.decode(result)
        ----filelog.sys_error("-----deresult------", deresult)
        if deresult.code == 0 then
            if deresult.data and deresult.data.list and next(deresult.data.list) ~= nil then
                local is_vip = false 
                for key, value in pairs(deresult.data.list) do
                    if value.rid == rid then is_vip = true break end
                end
                return is_vip
            else
                return false
            end
        else
            return false
        end
    else
        return false
    end
end

function TalkLogic.init_data(talkobj, conf, attachconf)
	if conf == nil  then
		filelog.sys_error("TalkLogic.init_data conf == nil", conf)
		return false
	end
    --初始化桌子信息
	local now = timetool.get_time()
    local nodename = skynet.getenv("nodename")
	talkobj.uuid = nodename .. "_" .. attachconf.index .. "_" .. now
	talkobj.index = attachconf.index
	talkobj.state = IMTALKSTATE.TALK_STATE_WAIT_PLAYER_SITDOWN
	talkobj.create_rolename = attachconf.rolename
    talkobj.create_logo = attachconf.logo
	talkobj.create_time = now
    talkobj.conf = conf
    talkobj.talk_service = attachconf.talk_service
    talkobj.sitdown_player_num = 0
    talkobj.table_persist = attachconf.table_persist        --桌子没人时，保留时间
    talkobj.tradeid = attachconf.tradeid
    talkobj.min_player_num = 1             --桌子最小人数

    talkobj.is_disconnected = false

    --设置最大玩家数
    talkobj.conf.max_player_num = talkobj.conf.max_player_num or 1
	return true
end

function TalkLogic.entertalk(talkobj, rid, roledata, request)
    local playerinfo = roledata.info or {}
    local playermoney = roledata.money or {}

    --处理重进桌子
    if talkobj.rid ~= 0 and talkobj.rid == rid then
        local noticemsg = {
            rid = talkobj.rid,
            talk_index = talkobj.talk_index,    
        }
        ---TalkLogic.sendmsg_to_tableplayer(seat.rid,"reentertableN", noticemsg)
        if not talkobj.is_had_start then
            if talkobj.delete_talk_timer_id > 0 then
                timer.cleartimer(talkobj.delete_talk_timer_id)
                talkobj.delete_talk_timer_id = -1
            end
        end
    else
        talkobj.rid = rid
        talkobj.talk_type = request.client_type
        talkobj.playerinfo = {}
        talkobj.playerinfo.rid = rid
        talkobj.playerinfo.rolename = playerinfo.rolename or ""
        talkobj.playerinfo.logo = playerinfo.logo or ""
        talkobj.playerinfo.sex = playerinfo.sex or 0
        talkobj.playerinfo.ip_addr = roledata.ip_addr or playerinfo.ip_addr
        talkobj.playerinfo.gps_addr = roledata.gps_addr or playerinfo.gps_addr
        talkobj.playerinfo.recommrid =  playerinfo.recommrid           --推荐人rid
        talkobj.playerinfo.agencyrid =  playerinfo.agencyrid           --代理rid
        talkobj.playerinfo.agencylevel =  playerinfo.agencylevel or 0  --代理等级，0表示不是代理
        talkobj.playerinfo.level = playerinfo.level or 0
        talkobj.playerinfo.intro = playerinfo.intro or ""
        talkobj.playerinfo.upvoted_num = playerinfo.upvoted_num
        talkobj.playerinfo.downvoted_num = playerinfo.downvoted_num
        talkobj.playerinfo.logoframe = playerinfo.logoframe

        talkobj.playerinfo.coin = playermoney.coin or 0
        talkobj.playerinfo.lock_coin = playermoney.lock_coin or 0
        talkobj.playerinfo.diamond = playermoney.diamond or 0
        talkobj.playerinfo.lock_diamond = playermoney.lock_diamond or 0
        talkobj.playerinfo.is_vip = false
        local player_is_vip = TalkLogic.check_player_is_vip(rid)
        talkobj.playerinfo.is_vip = player_is_vip
        talkobj.sitdown_player_num = talkobj.sitdown_player_num + 1
        talkobj.state = IMTALKSTATE.TALK_STATE_PLAYER_SITDOWN
        talkobj.last_send_time = timetool.get_time()
        local status, result = skynet.pcall(skynet.call, ".talkcache", "lua", "init_talk_cache", talkobj.rid)
    end
	if talkobj.delete_talk_timer_id > 0 then
		timer.cleartimer(talkobj.delete_talk_timer_id)
		talkobj.delete_talk_timer_id = -1
	end

    if talkobj.state == IMTALKSTATE.TALK_STATE_PLAYER_DISCONNECTED then
        talkobj.state = IMTALKSTATE.TALK_STATE_PLAYER_SITDOWN
    end
    talkobj.is_disconnected = false
    TalkLogic.update_talk_heart_time(talkobj)
end

function TalkLogic.leavetalk(talkobj, request)
    talkobj.state = IMTALKSTATE.TALK_STATE_PLAYER_LEAVE

    skynet.send(".router","lua","leave_talk",nil,talkobj.rid,talkobj.index)

    skynet.send(".talkcache", "lua", "clearcache", talkobj.rid)

    if talkobj.delete_talk_timer_id == -1 then
        talkobj.delete_talk_timer_id = timer.settimer(1*100, "delete_talk", {})
    end
end


function TalkLogic.reentertalk(talkobj, request)
    if talkobj.state == IMTALKSTATE.TALK_STATE_PLAYER_DISCONNECTED then
        talkobj.state = IMTALKSTATE.TALK_STATE_PLAYER_SITDOWN
    end
    talkobj.is_disconnected = false
end
--
-- 通知桌上除某玩家之外的所有玩家
-- rid 排除的玩家
--
function TalkLogic.sendmsg_to_otheralltableplayer( tableobj,rid, msgname, message)
    local retcode,retstr,msgbody
    if message and message.retcode  then
		retcode = tonumber(message.retcode)
		retstr = message.retstr or ""
		msgbody = message.msgbody or { }
    else
        msgbody = message
	end

    local rids = { }
    local seats = tableobj.seats
    for i,seat in pairs(seats) do
       if not seatlogic.is_empty(seat) and seat.rid ~= rid and 
       not seat.is_disconnected and not seat.is_robot then
            table.insert(rids,seat.rid)
       end 
    end

     if tableobj.waits ~= nil then
        for i,wait in pairs(tableobj.waits) do
            if wait.rid ~= rid and not wait.is_robot then
                table.insert(rids,wait.rid)
            end
        end
    end
    
    service:send_notice_to_players(rids, msgname, msgbody, retcode, retstr)
end

function TalkLogic.sendmsg_to_talkplayer( rid, msgname, message)
    -- local seat = TalkLogic.get_seat_by_rid(service.table_data,rid) or {}
    -- if seat.is_disconnected or seat.is_robot then
    --     return
    -- end

    local retcode,retstr,msgbody
    if message and message.retcode  then
		retcode = tonumber(message.retcode)
		retstr = message.retstr or ""
		msgbody = message.msgbody or { }
    else
        msgbody = message
	end

    local rids = { }
    table.insert(rids,rid) 
    service:send_notice_to_players(rids, msgname, msgbody, retcode, retstr)
end

--
-- 通知所有旁观列表玩家
--

function TalkLogic.sendmsg_to_allwaitplayer(tableobj, msgname, message)
    local retcode,retstr,msgbody
    if message and message.retcode  then
		retcode = tonumber(message.retcode)
		retstr = message.retstr or ""
		msgbody = message.msgbody or { }
    else
        msgbody = message
	end

    local rids = { }
    local waits = tableobj.waits
    for i,wait in pairs(waits) do
       if wait.rid and not wait.is_robot then
            table.insert(rids,wait.rid)
       end 
    end
    
    service:send_notice_to_players(rids, msgname, msgbody, retcode, retstr)
end

--
-- 更新桌子心跳时间
--
function TalkLogic.update_talk_heart_time(talkobj)
    talkobj.last_heart_time = timetool.get_time()
end

--
-- 设置所有座位状态
--
function TalkLogic.setallseatstate(tableobj, state)
	for k,value in pairs(tableobj.seats) do
		value.state = state
	end
end

--
--  改变金钱
--
function TalkLogic.change_money(rid, itemvalues)
    local comment = TalkLogic.create_comment()
    local status,result = skynet.pcall(cluster.call,"gatenode", ".router", "change_money", rid, itemvalues, comment)
    if not status then
        filelog.sys_error("change_money call failed!")
        return false
    end
    return result,comment
end

--------------------------------------------
--get方法
--

--
--根据rid获得座位对象
--
function TalkLogic.get_seat_by_rid(tableobj, rid)
	if tableobj.seats == nil then
		return nil
	end

	for index, seat in pairs(tableobj.seats) do
		if rid == seat.rid then
			return seat
		end
	end
	return nil
end

--- 根据玩家的rid查找玩家是否在旁观队列
-- @param tableobj 牌桌对象
-- @param rid  玩家rid
function TalkLogic.get_waitplayer_by_rid(tableobj, rid)
	for index, waitplayer in pairs(tableobj.waits) do
		if rid == waitplayer.rid then
			return waitplayer
		end
	end
	return nil
end

--
-- 获得游戏中玩家数
--
function TalkLogic.get_ingame_playernum(tableobj)
	local playernum = 0	
	for _, seat in pairs(tableobj.seats) do
		if gamelogic.is_ingame(tableobj.gameobj, seat) then
			playernum = playernum + 1
		end
	end
	return playernum
end

--------------------------------------------
--is方法
--

--- 判断当前桌子是否坐满
-- @param tableobj  牌桌对象
--
function TalkLogic.is_full(tableobj)
	return (tableobj.sitdown_player_num >= tableobj.conf.max_player_num)
end

---判断当前是否能够开始游戏
-- @param tableobj	牌桌对象
--
function TalkLogic.is_canstartgame(tableobj)
	return (tableobj.sitdown_player_num >= tableobj.min_player_num)
end

--- 判断游戏是否结束
-- @param tableobj 牌桌对象
--
function TalkLogic.is_gameend(tableobj)
	if tableobj.state == ESLWHTableState.TABLE_STATE_GAME_END
	or tableobj.state == ESLWHTableState.TABLE_STATE_WAIT_PLAYER_SITDOWN
	or tableobj.state == ESLWHTableState.TABLE_STATE_UNKNOW then
		return true
	end

	return false
end

--- 判断当前局是否已经结束游戏
-- @param tableobj 牌桌对象
--
function TalkLogic.is_onegameend(tableobj)
	if tableobj.state == ESLWHTableState.TABLE_STATE_ONE_GAME_REAL_END
	or tableobj.state == ESLWHTableState.TABLE_STATE_WAIT_ALL_READY 
    or tableobj.state == ESLWHTableState.TABLE_STATE_WAIT_ONE_GAME_START then
		return true
	end

	if not tableobj.is_ingame then
		return true
	end

	return TalkLogic.is_gameend(tableobj)
end
------------------------------------------------
--其他

--清空桌子对象数据
--
function TalkLogic.clear(tableobj)
	if tableobj.timer_id > 0 then
		timer.cleartimer(tableobj.timer_id)
		tableobj.timer_id = -1
	end

	if tableobj.delete_table_timer_id > 0 then
		timer.cleartimer(tableobj.delete_table_timer_id)
		tableobj.delete_table_timer_id = -1
	end

	for k,v in pairs(tableobj) do
		tableobj[k] = nil
	end
end

--
--创建comment
--
function  TalkLogic.create_comment()
    local tableobj = service.table_data
    local tradeid = skynet.call(".nodeuuid", "lua", "getuuid")
    local start_time = tableobj.one_start_time or 0
   
    return {table_uuid = tableobj.uuid ,table_tradeid = tradeid,start_time = start_time,jackpot_id = tableobj.cur_jackpot_id}
end

--
--断开连接(断线）
--
function TalkLogic.disconnect(talkobj, request, seat)
    if talkobj.is_disconnected == false then
        talkobj.is_disconnected = true
    end
    talkobj.state = IMTALKSTATE.TALK_STATE_PLAYER_DISCONNECTED
end

--
--发送跑马灯
--
function TalkLogic.send_horseracelamp(rolename, get_num)
	local horseconf = configdao.get_common_conf("horselampconf")
	if not horseconf or not horseconf[1] then return end
	local formatname = string.format(ELAMPCOLOR.GREEN, rolename)
	local formatnum = string.format(ELAMPCOLOR.RED, tostring(get_num))
	local horsestring = string.format(horseconf[1], formatname, EGameName, formatnum)
	skynet.pcall(cluster.send, "gatenode", ".router", "addpopmessage", horsestring)
end

function TalkLogic.check_is_willautoreplay(rid, request)
    filelog.sys_error("---------TalkLogic.check_is_willautoreplay----------", rid, request)
    local send_to_rid = request.send_to_rid
    local message = json.decode(request.message) or {}
    if type(message) == "table" and next(message) == nil then return end
    local is_replay = false
    filelog.sys_error("---------decode, message-------", message)
    if tonumber(message.mType) == IMMTYPE.IMMTYPE_ZHIFU_WECHAT or 
       tonumber(message.mType) == IMMTYPE.IMMTYPE_ZHIFU_ALIPAY or
       tonumber(message.mType) == IMMTYPE.IMMTYPE_ZHIFU_BANKCARD then
        local status, result = skynet.pcall(skynet.call, ".autoreplay", "lua", "sendvipchargeautoreplay", message.message, 
            tonumber(message.toRid), tonumber(message.fromRid), tonumber(message.mType))
        is_replay = true
    end
    return is_replay 
end

return TalkLogic